package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.TsCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.redisson.RedissonConfig;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Random;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;
    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;
    @Autowired
    private AlbumStatMapper albumStatMapper;
    @Autowired
    private RabbitService rabbitService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo, Long userId) {
        // album_info 专辑表   album_attribute_value 专辑属性值表 album_stat 专辑统计表
        //专辑表
        //创建对象
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        //添加用户id
        albumInfo.setUserId(userId);
        //设置声音总数暂时默认值为0;
        //	tracks_for_free 免费试听集数? 除免费的专辑之外都要试听！试听的集数应该是从页面传递来！固定值10;

//        if (!albumInfoVo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)) {
//            albumInfo.setTracksForFree(10);
//            //  设置购买须知;
//        }
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            albumInfo.setTracksForFree(10);
            //  设置购买须知;
        }
        //  审核状态;status！ 需要身份验证：平台管理员或就是专辑发布者;
        //  辑发布者--> 待审核！(钉钉邮件)--> 管理员--> 人工审核通过！(发送邮件钉钉)！ 做OA 系统：
        //  工作流 activity; 或 flowable 工作流引擎; 使用ai 完成工作流 扣子；
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        albumInfoMapper.insert(albumInfo);

        //album_attribute_value 专辑属性值表
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        //判断是否为空
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                albumAttributeValue.setAlbumId(albumInfo.getId());
                albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
                albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
                albumAttributeValueMapper.insert(albumAttributeValue);
            }

        }
        //album_stat 专辑统计表
        //初始化专辑统计数据
        //播放量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_PLAY);
        //订阅量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_SUBSCRIBE);
        //购买量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_BROWSE);
        //评论数
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_COMMENT);
        //保存的时候 发送一个消息 实现上架功能!
        //判断isOpen 字段是1 或 0
        if ("1".equals(albumInfo.getIsOpen())) {
            //上架
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumInfo.getId());
        }

    }

    private void saveAlbumStat(Long albumId, String statPlay) {
        //创建对象
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatType(statPlay);
        //初始化值
        albumStat.setStatNum(new Random().nextInt(10000));
        albumStatMapper.insert(albumStat);

    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(Page<AlbumListVo> albumListVoPage, AlbumInfoQuery albumInfoQuery) {
        return albumInfoMapper.selectUserAlbumPage(albumListVoPage, albumInfoQuery);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAlbumInfoById(Long albumId) {
        //删除album_info
        albumInfoMapper.deleteById(albumId);
        //删除album_attribute_value
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        //删除album_stat
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
    }

    @Override
    @TsCache(prefix = RedisConstant.ALBUM_INFO_PREFIX)
    public AlbumInfo getAlbumInfo(Long albumId) {
        //先查询缓存 看是否存在 有数据!
        //        String dataKey = RedisConstant.ALBUM_INFO_PREFIX + albumId;
        //        try {
        //            //  选择数据：string;
        //            AlbumInfo albumInfo = (AlbumInfo) this.redisTemplate.opsForValue().get(dataKey);
        //            //  判断数据是否为空
        //            if (null == albumInfo){
        //                //  说明缓存没有数据
        //                log.info("缓存中没有数据");
        //                //  查询数据库; 为了避免在高并发的情况下出现缓存击穿，使用分布式锁，保护资源.
        //                String dateLockKey = RedisConstant.ALBUM_LOCK_SUFFIX + albumId;
        //                RLock lock = redissonClient.getLock(dateLockKey);
        //                //  上锁：
        //                lock.lock();
        //                try {
        //                    //  查询数据库之前再次判断缓存是否存在！
        //                    albumInfo = (AlbumInfo) this.redisTemplate.opsForValue().get(dataKey);
        //                    if (null != albumInfo){
        //                        //  缓存有数据，直接返回;
        //                        return albumInfo;
        //                    }
        //                    //  业务逻辑; 从数据库中获取数据;
        //                    albumInfo = getAlbumInfoDB(albumId);
        //                    //  判断数据库中的数据一定有么?
        //                    if (null == albumInfo){
        //                        //  说数据库中根本没有这条记录;最好向缓存缓存一个空值;
        //                        this.redisTemplate.opsForValue().set(dataKey,new AlbumInfo(),RedisConstant.ALBUM_TEMPORARY_TIMEOUT, TimeUnit.SECONDS);
        //                        return new AlbumInfo();
        //                    }
        //                    this.redisTemplate.opsForValue().set(dataKey,albumInfo,RedisConstant.ALBUM_TIMEOUT, TimeUnit.SECONDS);
        //                    //  返回数据
        //                    return albumInfo;
        //                } catch (Exception e) {
        //                    log.error(e.getMessage(),e);
        //                } finally {
        //                    //  解锁
        //                    lock.unlock();
        //                }
        //            } else {
        //                //  直接返回缓存数据：
        //                log.info("缓存中有数据");
        //                return albumInfo;
        //            }
        //        } catch (Exception e) {
        //            //  发送钉钉或邮件告知管理员服务器宕机;
        //            log.error(e.getMessage(),e);
        //        }
        //  从数据库中获取数据
        return getAlbumInfoDB(albumId);
    }

    private @Nullable AlbumInfo getAlbumInfoDB(Long albumId) {
        //查询album_info
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        // album_attribute_value
        if (null != albumInfo) {

            List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueMapper.
                    selectList(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
            albumInfo.setAlbumAttributeValueVoList(albumAttributeValues);
        }

        return albumInfo;
    }

    @Override
    public void updateAlbumInfo(AlbumInfoVo albumInfoVo, Long albumId) {
        //属性拷贝
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setId(albumId);
        albumInfoMapper.updateById(albumInfo);
        //删除旧数据
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        //添加新数据
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                albumAttributeValue.setAlbumId(albumId);
                albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
                albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
                albumAttributeValueMapper.insert(albumAttributeValue);
            }
        }
        //  发送消息，修改专辑-上架-下架
        //  判断isOpen 字段是 1 或 0
        if ("1".equals(albumInfoVo.getIsOpen())) {
            //  上架
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumId);
            //  将专辑Id保存到布隆过滤器!
            redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER).add(albumId);
        } else {
            //  下架;
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId);
        }
    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        Page<AlbumInfo> albumInfoPage = new Page<>(1, 20);
        LambdaQueryWrapper<AlbumInfo> wrapper = new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId);
        wrapper.orderByDesc(AlbumInfo::getId).select(AlbumInfo::getId, AlbumInfo::getAlbumTitle);
        Page<AlbumInfo> page = albumInfoMapper.selectPage(albumInfoPage, wrapper);
        return page.getRecords();
    }

    @Override
    public AlbumStatVo getAlbumStatVoByAlbumId(Long albumId) {
        //	调用mapper 层方法
        return albumInfoMapper.selectAlbumStat(albumId);
    }


}
